﻿//-------------
// <copyright file="UserRepository.cs" company="Uncas">
//     Copyright (c) Ole Lynge Sørensen. All rights reserved.
// </copyright>
//-------------

namespace Uncas.Katas.SimpleMembership.Domain
{
    using System.Collections.Generic;
    using System.Web.Security;

    /// <summary>
    /// Repository for user data.
    /// </summary>
    public class UserRepository : IUserRepository
    {
        /// <summary>
        /// Creates the user.
        /// </summary>
        /// <param name="userName">The user name.</param>
        /// <param name="password">The password.</param>
        /// <param name="email">The email.</param>
        public void CreateUser(
            string userName,
            string password,
            string email)
        {
            Membership.CreateUser(userName, password, email);
        }

        /// <summary>
        /// Gets the users.
        /// </summary>
        /// <returns>The users.</returns>
        public IEnumerable<User> GetUsers()
        {
            var result = new List<User>();
            var membershipUsers = Membership.GetAllUsers();
            foreach (MembershipUser mu in membershipUsers)
            {
                var user = DomainMapper.MapMembershipUserToDomain(
                    mu, this.GetRolesForUser(mu.UserName));
                result.Add(user);
            }

            return result;
        }

        /// <summary>
        /// Gets all roles.
        /// </summary>
        /// <returns>The roles.</returns>
        public IEnumerable<Role> GetAllRoles()
        {
            var result = new List<Role>();
            var roleNames = Roles.GetAllRoles();
            foreach (var roleName in roleNames)
            {
                var role = new Role
                {
                    RoleName = roleName,
                    NumberOfUsers = Roles.GetUsersInRole(roleName).Length
                };
                result.Add(role);
            }

            return result;
        }

        /// <summary>
        /// Gets all role names.
        /// </summary>
        /// <returns>The role names.</returns>
        public IEnumerable<string> GetAllRoleNames()
        {
            return Roles.GetAllRoles();
        }

        /// <summary>
        /// Gets the roles for user.
        /// </summary>
        /// <param name="userName">The user name.</param>
        /// <returns>The roles for the given user.</returns>
        public IEnumerable<string> GetRolesForUser(string userName)
        {
            return Roles.GetRolesForUser(userName);
        }

        /// <summary>
        /// Determines whether [is user in role] [the specified userName].
        /// </summary>
        /// <param name="userName">The user name.</param>
        /// <param name="roleName">Name of the role.</param>
        /// <returns>
        /// <c>true</c> if [is user in role] [the specified userName]; otherwise, <c>false</c>.
        /// </returns>
        public bool IsUserInRole(string userName, string roleName)
        {
            return Roles.IsUserInRole(userName, roleName);
        }

        /// <summary>
        /// Removes the user from role.
        /// </summary>
        /// <param name="userName">The user name.</param>
        /// <param name="roleName">Name of the role.</param>
        public void RemoveUserFromRole(string userName, string roleName)
        {
            Roles.RemoveUserFromRole(userName, roleName);
        }

        /// <summary>
        /// Adds the user to role.
        /// </summary>
        /// <param name="userName">The user name.</param>
        /// <param name="roleName">Name of the role.</param>
        public void AddUserToRole(string userName, string roleName)
        {
            Roles.AddUserToRole(userName, roleName);
        }

        /// <summary>
        /// Creates the role.
        /// </summary>
        /// <param name="roleName">Name of the role.</param>
        public void CreateRole(string roleName)
        {
            Roles.CreateRole(roleName);
        }

        /// <summary>
        /// Gets the users in role.
        /// </summary>
        /// <param name="roleName">Name of the role.</param>
        /// <returns>The users in the given role.</returns>
        public IEnumerable<string> GetUsersInRole(string roleName)
        {
            return Roles.GetUsersInRole(roleName);
        }

        /// <summary>
        /// Deletes the user.
        /// </summary>
        /// <param name="userName">The user name.</param>
        public void DeleteUser(string userName)
        {
            Membership.DeleteUser(userName);
        }

        /// <summary>
        /// Updates the user.
        /// </summary>
        /// <param name="userName">The user name.</param>
        /// <param name="email">The email.</param>
        /// <param name="isApproved">if set to <c>true</c> [is approved].</param>
        public void UpdateUser(
            string userName,
            string email,
            bool isApproved)
        {
            var user = Membership.GetUser(userName);
            user.IsApproved = isApproved;
            user.Email = email;
            Membership.UpdateUser(user);
        }

        /// <summary>
        /// Gets the user.
        /// </summary>
        /// <param name="userName">The user name.</param>
        /// <returns>The given user.</returns>
        public MembershipUser GetUser(string userName)
        {
            return Membership.GetUser(userName);
        }

        /// <summary>
        /// Changes the password.
        /// </summary>
        /// <param name="userName">The user name.</param>
        /// <param name="password">The password.</param>
        public void ChangePassword(
            string userName,
            string password)
        {
            var user = Membership.GetUser(userName);
            string tempPassword = user.ResetPassword();
            user.ChangePassword(tempPassword, password);
        }

        /// <summary>
        /// Validates the credentials.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <param name="password">The password.</param>
        /// <returns>
        /// True if the credentials are valid, otherwise false.
        /// </returns>
        public bool ValidateCredentials(
            string userName,
            string password)
        {
            return Membership.ValidateUser(userName, password);
        }
    }
}